package com.panopset.swing;

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

/**
 * Full screen window. Esc key always disposes it. Usually you would add an
 * animated panel, such as a com.panopset.gui.Osgw panel, using getFrame().
 *
 * Override load and save methods to load and save state, as needed.
 *
 * @author Karl Dinwiddie
 *
 */
public class FullScreenWindow {

    /**
     * Graphics environment.
     */
    private final GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();

    /**
     * Graphics device.
     */
    private final GraphicsDevice gd = ge.getDefaultScreenDevice();

    /**
     * Full screen window frame.
     */
    private final JFrame frame;

    /**
     * @return Full screen window frame.
     */
    public final JFrame getFrame() {
        return frame;
    }

    /**
     * Report key pressed.
     *
     * @param keyCode
     *            Key that was pressed.
     */
    protected void reportKeyPressed(final int keyCode) {

    }

    /**
     * Report mouse clicked.
     *
     * @param p
     *            Clicked point.
     */
    protected void reportMouseClicked(final Point p) {

    }

    /**
     * Report mouse moved.
     *
     * @param p
     *            Moved point.
     */
    protected void reportMouseMoved(final Point p) {

    }

    /**
     * Report mouse dragged.
     *
     * @param p
     *            Dragged point.
     */
    protected void reportMouseDragged(final Point p) {

    }

    /**
     * Constructor.
     */
    public FullScreenWindow() {
        frame = new JFrame();
        frame.setUndecorated(true);
        frame.setAlwaysOnTop(true);
        frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());
        frame.setLocation(0, 0);
        frame.addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseDragged(final MouseEvent e) {
                reportMouseDragged(e.getPoint());
            }

            @Override
            public void mouseMoved(final MouseEvent e) {
                reportMouseMoved(e.getPoint());
            }

        });
        frame.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(final MouseEvent e) {
                reportMouseClicked(e.getPoint());
            }

        });
        frame.addKeyListener(new KeyAdapter() {

            public void keyPressed(final KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    quit();
                } else {
                    reportKeyPressed(e.getKeyCode());
                }
            }

        });
    }

    /**
     * Override as needed to load state.
     */
    protected void load() {
    }

    /**
     * Override as needed to save state.
     */
    protected void save() {
    }

    /**
     * Load state and show the full screen window.
     */
    public final void show() {
        load();
        frame.setVisible(true);
        gd.setFullScreenWindow(frame);
    }

    /**
     * Dispose the full screen window and save state.
     */
    public final void quit() {
        save();
        Osgw.close();
        gd.setFullScreenWindow(null);
        frame.dispose();
    }
}
